package org.common.utils.rpc.generator.handler.methodbody;

import org.common.utils.rpc.entity.Metadata;
import org.common.utils.rpc.entity.RpcRequest;
import org.common.utils.rpc.generator.entity.GeneratorInfo;

import java.lang.reflect.Method;

/**
 * 根据返回值类型，进行方法体处理抽象类
 * @author zhouzhibing
 * @date 2025/11/15 18:41
 */
public abstract class AbstractHandler {

    /**
     * 参数前缀
     */
    private static final String ARG_PREFIX = "arg";

    protected final ReturnType type;

    public AbstractHandler(ReturnType type) {
        this.type = type;
    }

    /**
     * 处理方法体，对象中内置了，"rpcClient" 这个对象引用 ，可直接操作rpc。
     * @param generatorInfo 生成信息，包含接口类，方法名，参数等信息
     * @return 方法体字符串
     */
    public abstract String handler(GeneratorInfo generatorInfo);

    /**
     * 获取参数数组字符串
     * @param parameterTypes 参数类型数组
     * @return 参数字符串
     */
    private String getArgString(Class<?>[] parameterTypes) {
        int length = parameterTypes.length;
        StringBuilder argArray = new StringBuilder();
        argArray.append("Object [] argArray = new Object[").append(length).append("];");
        for (int i = 0; i < length; i++) {
            Class<?> parameterType = parameterTypes[i];
            String value = getValueOf(parameterType , i);
            argArray.append("\n");
            argArray.append("argArray[").append(i).append("] = ").append(value).append(";");
        }
        argArray.append("\n");
        return argArray.toString();
    }

    /**
     * 获取参数值
     * @param parameterType 参数类型
     * @param index 参数索引
     * @return 参数值
     */
    private String getValueOf(Class<?> parameterType , int index) {
        String name = ARG_PREFIX + index;
        return switch (parameterType.getName()) {
            case "int" -> "Integer.valueOf("+ name + ")";
            case "long" -> "Long.valueOf(" + name + ")";
            case "double" -> "Double.valueOf(" + name + ")";
            case "float" -> "Float.valueOf(" + name + ")";
            case "boolean" -> "Boolean.valueOf(" + name + ")";
            case "char" -> "Character.valueOf(" + name + ")";
            case "byte" -> "Byte.valueOf(" + name + ")";
            case "short" -> "Short.valueOf(" + name + ")";
            case "String" -> "String.valueOf(" + name + ")";
            default -> name;
        };
    }

    /**
     * 获取Rpc请求字符串
     * @param generatorInfo 生成信息
     * @return Rpc请求字符串
     */
    protected String getRequest(GeneratorInfo generatorInfo) {
        Method method = generatorInfo.getMethod();
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        String metaDataClass = Metadata.class.getName();
        String requestClass = RpcRequest.class.getName();

        String body = getArgString(parameterTypes);
        body += "%s metadata = (%s)this.metadataMap.get(\"%s\");\n".formatted(metaDataClass, metaDataClass, methodName);
        body += "%s request = new %s(metadata , %s);".formatted(requestClass , requestClass , "argArray");
        return body;
    }

    public String getTypeName() {
        return type.getName();
    }
}
